#ifndef DS18B20_H
#define DS18B20_H

#include "mgos.h"
#include "mgos_onewire.h"
#include "stdio.h"

#define BYTE_READ 2

struct mgos_onewire_search_state
{
  int search_mode;
  int last_device;
  int last_discrepancy;
  int last_family_discrepancy;
  uint8_t rom[8];
  uint8_t crc8;
};
struct mgos_onewire
{
  int pin;
  uint8_t *res_rom;
  struct mgos_onewire_search_state sst;
};

class DS18b20
{
public:
  DS18b20(int);
  void init();
  double getTemp();        // 返回温度
  void setPrecision(int);  // 设置精度
  void begin_conversion(); // 读温度
  double toDouble(uint16_t data);
  //cb：timer
  static void cb_read(void *arg)
  {
    DS18b20 *pClass = reinterpret_cast<DS18b20 *>(arg);
    if (pClass == NULL)
    {
      LOG(LL_INFO, ("pClass is NULL.\n"));
      return;
    }

    if (!mgos_onewire_reset(pClass->ow))
    {
      LOG(LL_INFO, ("reset for read failed\n"));
      return;
    }

    mgos_onewire_skip(pClass->ow);
    mgos_onewire_write(pClass->ow, 0xbe);
    //read
    uint8_t data[BYTE_READ];
    mgos_onewire_read_bytes(pClass->ow, data, BYTE_READ);
    uint16_t *p_data = (uint16_t *)(data);
    *p_data &= ~1;
    *p_data <<= 4;
    pClass->temp = pClass->toDouble(*p_data);
    //printf("ds18b20 temp is:%3.1f\n", pClass->temp);

    mgos_onewire_reset(pClass->ow);
  }

private:
  double temp;
  struct mgos_onewire *ow;
  int pin;
};

#endif